package com.xy.etl.service;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ReflectUtil;
import com.xy.core.annotation.ConfigAttribute;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 配置
 */
@Component
public class YmlConfig {

    @Resource
    private Environment environment;

    /**
     * 属性
     *
     * @param key
     * @return
     */
    public String getProperty(String key) {
        return environment.getProperty(key);
    }

    /**
     * 取得属性
     *
     * @param key
     * @param defaultValue
     * @return
     */
    public String getProperty(String key, String defaultValue) {
        return environment.getProperty(key, defaultValue);
    }

    /**
     * 配置对象
     *
     * @param pre
     * @param object
     * @param <T>
     * @return
     * @throws Exception
     */
    public <T> T getProperty(String pre, T object) throws Exception {
        Field[] fields = ReflectUtil.getFields(object.getClass());
        String key;
        Object value;
        ConfigAttribute configAttribute;
        for (Field field : fields) {
            configAttribute = field.getAnnotation(ConfigAttribute.class);
            if (configAttribute == null || configAttribute.value() == null || configAttribute.value().trim().length() == 0) {
                key = pre + "." + field.getName();
                value = val(field, key);
            } else {
                key = pre + "." + configAttribute.value().trim();
                value = val(field, key);
                if (value == null) {
                    key = pre + "." + field.getName();
                    value = val(field, key);
                }
            }
            ReflectUtil.setFieldValue(object, field, value);
        }
        return object;
    }

    /**
     * 取得值
     *
     * @param field
     * @param prefix
     * @return
     */
    private Object val(Field field, String prefix) {
        if (field.getType().isAssignableFrom(List.class)) {
            int idx = 0;
            String key;
            String value;
            List<String> valueList = new ArrayList<>();
            while (true) {
                key = prefix + "[" + idx + "]";
                if (!environment.containsProperty(key)) {
                    break;
                }
                value = environment.getProperty(key);
                if (value == null) {
                    value = "";
                }
                valueList.add(value);
                idx++;
            }
            return valueList;
        } else {
            String value = environment.getProperty(prefix);
            if (value == null || value.length() == 0) {
                return null;
            }
            try {
                if (field.getType().isAssignableFrom(Integer.class)) {
                    return Integer.valueOf(value.trim());
                } else if (field.getType().isAssignableFrom(Long.class)) {
                    return Integer.valueOf(value.trim());
                } else if (field.getType().isAssignableFrom(BigDecimal.class)) {
                    return BigDecimal.valueOf(Double.valueOf(value.trim()));
                } else if (field.getType().isAssignableFrom(Float.class)) {
                    return Float.valueOf(value.trim());
                } else if (field.getType().isAssignableFrom(Double.class)) {
                    return Double.valueOf(value.trim());
                } else if (field.getType().isAssignableFrom(Date.class)) {
                    return DateUtil.parse(value.trim());
                } else {
                    return value;
                }
            } catch (Exception ex) {
                ex.printStackTrace();
                return null;
            }

        }
    }
}
